package com.etool.commons.dao;


import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;

import com.cache.simplecache.SimpleCacheManager;
import com.etool.commons.sql.List2Map;
import com.etool.commons.sql.SearchCondition;
import com.etool.commons.sql.SqlCountUtil;
import com.etool.commons.sql.SqlUtil;
import com.etool.commons.utils.PageHolder;
import com.etool.commons.utils.ReflectionUtils;


public abstract class DaoBase<T> {

	
	protected Class targetClass;
	
	protected String tableName;
	
	protected SimpleCacheManager simpleCacheManager;
	
	protected NamedParameterJdbcTemplate jdbc;
	
	
	private RowMapper<T> targetRm;
	

	
	
	public DaoBase()
	{	
		this.targetClass = ReflectionUtils.getSuperClassGenricType(getClass());
		this.targetRm=ParameterizedBeanPropertyRowMapper.newInstance(targetClass);
	}

	public int insert(T t)
	{
		SqlParameterSource paramSource=new BeanPropertySqlParameterSource(t);
		String sql=SqlUtil.generateInsertSql(targetClass,tableName);
		GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
		jdbc.update(sql, paramSource,keyHolder);
		return keyHolder.getKey().intValue();
	}
	
	public int replace(T t)
	{
		SqlParameterSource paramSource=new BeanPropertySqlParameterSource(t);
		String sql=SqlUtil.generateReplaceSql(targetClass, tableName);
		return jdbc.update(sql, paramSource);
		
	}
	
	public int delete(T t,List<SearchCondition> params)
	{
		String sql=SqlUtil.generateDeleteSql(t, params, tableName);
		return jdbc.update(sql, List2Map.execute(params));
	}

	public List<T> select(List<SearchCondition> params)
	{
		String sql=SqlUtil.generateSelectSql(targetClass, params, tableName);
		return jdbc.query(sql, List2Map.execute(params), targetRm);
	}
	
	public void  select(PageHolder<T> pageHolder, List<SearchCondition> params,String orderBy,String groupBy)
	{
		String sql=SqlUtil.generateSelectSql(targetClass, params, tableName);
		
		String countSql=SqlCountUtil.getCountSql(sql);
		int count=getCount(countSql,params);
		pageHolder.setRowCount(count);
		
		if(StringUtils.isNotEmpty(groupBy))
		{
			sql+=" group by "+groupBy;
		}
		if(StringUtils.isNotEmpty(orderBy))
		{
			sql+=" order by "+orderBy;
		}
		sql+=" limit "+pageHolder.getRowOffset()+","+pageHolder.getPageSize();
		
		List<T> result= jdbc.query(sql,List2Map.execute(params), targetRm);
		
		pageHolder.setList(result);
		return ;
		
	}
	
	public int getCount(String sql,List<SearchCondition> params)
	{
		return jdbc.queryForInt(sql,List2Map.execute(params) );
	}
	


	
	public abstract void setSimpleCacheManager(SimpleCacheManager simpleCacheManager);
	
	public abstract void setJdbc(NamedParameterJdbcTemplate jdbc);


	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public void setTargetClass(Class targetClass) {
		this.targetClass = targetClass;
	}
	
	
	
}
